//-------------------------------------------------------------------------------------
// <copyright file="LinkMsi.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <author>Greg Beech</author>
// <email>gregbee@microsoft.com</email>
// <date>2004-04-16</date>
// <summary>
//      Links intermediate *.wixobj files to build a complete MSI.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Wix
{
    #region Using directives

    using System.IO;
    using System.Text;

    #endregion

    /// <summary>
    /// Links intermediate <b>*.wixobj</b> files to build a complete MSI. The 
    /// <see cref="Microsoft.Sdc.Tasks.Wix.CompileMsi"/> task can be used to create the
    /// intermediate files that this task expects as input.
    /// </summary>
    /// <remarks>
    /// <para>
    /// <b>About Wix:</b> Wix was originally a Microsoft tool that has been released into the open source
    /// community under the Common Public License. The binaries and source code can be downloaded from
    /// <a href="http://sourceforge.net/projects/wix">SourceForge</a>.
    /// </para>
    /// <code><![CDATA[<LinkMsi SourceFiles="sourceFiles" OutputFile="outputFile" WixPath="wixPath" BasePath="basePath" InformationLevel="informationLevel" WarningLevel="warningLevel" TreatWarningsAsErrors="treatWarningsAsErrors" KeepTemporaryFiles="keepTemporaryFiles" />]]></code>
    /// <para>where:</para>
    /// <para><i>sourceFiles (Required)</i></para>
    /// <para>
    /// A delimited list of the source files to generate the MSI from. These should have the extension *.wixobj.
    /// </para>
    /// <para><i>outputFile (Required)</i></para>
    /// <para>
    /// The path to the MSI to produce. This should have the extension *.msi.
    /// </para>
    /// <para><i>wixPath (Required)</i></para>
    /// <para>
    /// The path to the directory that the Wix executables reside in.
    /// </para>
    /// <para><i>basePath</i></para>
    /// <para>
    /// The base path used to locate all files if they are provided as a relative path. The default
    /// is the current directory.
    /// </para>
    /// <para><i>informationLevel</i></para>
    /// <para>
    /// An integer between zero (verbose information) and three (no information). The default is zero.
    /// </para>
    /// <para><i>warningLevel</i></para>
    /// <para>
    /// An integer between zero (all warnings) and three (no warnings). The default is zero.
    /// </para>
    /// <para><i>treatWarningsAsErrors</i></para>
    /// <para>
    /// <b>true</b> if warnings are treated as errors, or <b>false</b> otherwise. The default is <b>false</b>.
    /// </para>
    /// <para><i>keepTemporaryFiles</i></para>
    /// <para>
    /// <b>true</b> if temporary files should be kept, or <b>false</b> otherwise. Keeping the temporary files
    /// can be useful for debugging purposes. The default is <b>false</b>.
    /// </para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test">
    ///         <LinkMsi 
    ///             SourceFiles="IntermediateFile1.wixobj;IntermediateFile2.wixobj" 
    ///             OutputFile="MyPackage.msi" 
    ///             WixPath="C:\Program Files\Wix" 
    ///             BasePath="C:\Build\Msi\ObjectFiles" 
    ///             InformationLevel="1" 
    ///             WarningLevel="2" 
    ///             TreatWarningsAsErrors="true" 
    ///             KeepTemporaryFiles="false" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public sealed class LinkMsi : WixTaskBase
    {
        #region Member Variables

        private string basePath;
        private bool keepTemporaryFiles = false;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the base path used to locate all files if they are provided as a relative path.
        /// </summary>
        /// <value>
        /// The base path used to locate all files if they are provided as a relative path.
        /// </value>
        public string BasePath
        {
            get { return this.basePath; }
            set { this.basePath = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether temporary files are kept during the linking process. This can be useful
        /// for debugging purposes.
        /// </summary>
        /// <value>
        /// <b>true</b> if temporary files should be kept, or <b>false</b> otherwise.
        /// </value>
        public bool KeepTemporaryFiles
        {
            get { return this.keepTemporaryFiles; }
            set { this.keepTemporaryFiles = value; }
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// Executes the task.
        /// </summary>
        protected override void InternalExecute()
        {
            StringBuilder argumentsBuilder = new StringBuilder();
            if (!string.IsNullOrEmpty(this.BasePath))
            {
                argumentsBuilder.Append(string.Concat("-b ", EscapeArgument(this.BasePath), " "));
            }

            argumentsBuilder.Append("-nologo ");
            if (this.keepTemporaryFiles)
            {
                argumentsBuilder.Append("-notidy ");
            }

            this.AppendInformationAndWarningLevelArguments(argumentsBuilder);
            argumentsBuilder.Append(string.Concat("-out ", EscapeArgument(this.OutputFile), " "));
            foreach (string sourceFile in this.SourceFiles)
            {
                string extension;
                extension = Path.GetExtension(sourceFile);
                if ((extension != ".wixobj") && (extension != ".wixlib"))
                {
                    this.Log.LogWarning("Source file with unexpected extension encountered. Expected *.wixobj or *.wixlib but actual extension is *" + extension);
                }

                argumentsBuilder.Append(string.Concat(EscapeArgument(sourceFile), " "));
            }

            if (!string.IsNullOrEmpty(this.LocaleFile))
            {
                argumentsBuilder.Append(string.Concat("-loc ", EscapeArgument(this.LocaleFile), " "));
            }

            string executablePath = Path.Combine(this.WixPath, WixTaskBase.LinkerName);
            string arguments = argumentsBuilder.ToString(0, argumentsBuilder.Length - 1);
            this.RunWixProcess(executablePath, arguments);
        }

        #endregion
    }
}